﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;


namespace BEX.Core.Exchange
{
    public abstract class Exchange
    {
        private List<DateTime> _requestTimes = new List<DateTime>();

        private int _requestCount = 0;

        public int RequestCount
        {
            get
            {
                return _requestCount;
            }
            set
            {
                int before = _requestCount;
                DateTime _requestTime = DateTime.Now;

                _requestCount = value;

                for (int i = 0; i < (_requestCount - before); ++i)
                {
                    _requestTimes.Add(_requestTime);
                }

                _requestTimes.RemoveAll(_time => (_requestTime - _time).TotalMinutes > 10);
                _requestTimes.Sort();

            }
        }

        public int ID { get; set; }

        public ExchangeType Type { get { return (ExchangeType)ID; } set { ID = (int)value; } }

        public string Name { get; set; }

        public int QueryFrequency { get; set; }

        public Exchange(ExchangeType t)
        {
            //SourceExchange = source;
        }

        internal abstract Tick GetCurrentTick(CurrencyPair pair);

        public Tick GetTick(CurrencyPair pair)
        {
            if (SupportedPairs.Contains(pair))
            {

                return GetCurrentTick(pair);
            }
            else
                throw new Exception("Currency Pair " + pair.ToString() + " is not supported by Exchange " + Type.ToString());
        }

        protected abstract string _pairs
        {
            get;
        }

        private List<CurrencyPair> _supportedPairs = null;

        public List<CurrencyPair> SupportedPairs
        {
            get
            {

                if (_supportedPairs == null)
                {
                    string[] _spPairs = _pairs.Split(';');

                    foreach (string _p in _spPairs)
                    {

                        if (_supportedPairs == null)
                            _supportedPairs = new List<CurrencyPair>();


                        string[] _c = _p.Split('^');

                        _supportedPairs.Add(
                            new CurrencyPair() { Base = (CurrencyType)Convert.ToInt32(_c[0]), Counter = (CurrencyType)Convert.ToInt32(_c[1]) });
                    }


                }

                return _supportedPairs;
            }
        }

        protected abstract string _baseUrl
        { get; }

        protected abstract string _tickPath
        { get; }

        public string TickerURL
        {
            get
            {
                Uri _base = new Uri(_baseUrl);

                return new Uri(_base, _tickPath).ToString();
            }
        }

    }

    public enum ExchangeType
    {
        COINBASE = 1,
        BTCE = 2,
        BITSTAMP = 3,
        TRADEHILL = 4,
        BITFINEX = 5,
        CAMPBX = 6,
        MTGOX = 7,
        UNKNOWN = 50
    }

    [Serializable]
    public struct CurrencyPair
    {
        public CurrencyType Base;
        public CurrencyType Counter;

        public string Title
        {
            get
            {
                return this.ToString();
            }
        }

        public static bool operator !=(CurrencyPair l, CurrencyPair r)
        {
            if (l.Base == r.Base
                && l.Counter == r.Counter)
                return false;
            else
                return true;

        }

        public static bool operator ==(CurrencyPair l, CurrencyPair r)
        {
            if (l.Base == r.Base
                && l.Counter == r.Counter)
                return true;
            else
                return false;
        }

        public override string ToString()
        {
            return Base.ToString() + "/" + Counter.ToString();
        }
    }
}
